home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Chat & Communication / Digsby build 37 / digsby_setup.exe / lib / aifc.pyo (.txt) < prev    next >
Python Compiled Bytecode  |  2008-10-13  |  23KB  |  909 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. import struct
  5. import __builtin__
  6. __all__ = [
  7.     'Error',
  8.     'open',
  9.     'openfp']
  10.  
  11. class Error(Exception):
  12.     pass
  13.  
  14. _AIFC_version = 0xA2805140L
  15. _skiplist = ('COMT', 'INST', 'MIDI', 'AESD', 'APPL', 'NAME', 'AUTH', '(c) ', 'ANNO')
  16.  
  17. def _read_long(file):
  18.     
  19.     try:
  20.         return struct.unpack('>l', file.read(4))[0]
  21.     except struct.error:
  22.         raise EOFError
  23.  
  24.  
  25.  
  26. def _read_ulong(file):
  27.     
  28.     try:
  29.         return struct.unpack('>L', file.read(4))[0]
  30.     except struct.error:
  31.         raise EOFError
  32.  
  33.  
  34.  
  35. def _read_short(file):
  36.     
  37.     try:
  38.         return struct.unpack('>h', file.read(2))[0]
  39.     except struct.error:
  40.         raise EOFError
  41.  
  42.  
  43.  
  44. def _read_string(file):
  45.     length = ord(file.read(1))
  46.     if length == 0:
  47.         data = ''
  48.     else:
  49.         data = file.read(length)
  50.     if length & 1 == 0:
  51.         dummy = file.read(1)
  52.     
  53.     return data
  54.  
  55. _HUGE_VAL = 1.79769e+308
  56.  
  57. def _read_float(f):
  58.     expon = _read_short(f)
  59.     sign = 1
  60.     if expon < 0:
  61.         sign = -1
  62.         expon = expon + 32768
  63.     
  64.     himant = _read_ulong(f)
  65.     lomant = _read_ulong(f)
  66.     if himant == himant and lomant == lomant:
  67.         pass
  68.     elif lomant == 0:
  69.         f = 0
  70.     elif expon == 32767:
  71.         f = _HUGE_VAL
  72.     else:
  73.         expon = expon - 16383
  74.         f = (himant * 0x100000000L + lomant) * pow(2, expon - 63)
  75.     return sign * f
  76.  
  77.  
  78. def _write_short(f, x):
  79.     f.write(struct.pack('>h', x))
  80.  
  81.  
  82. def _write_long(f, x):
  83.     f.write(struct.pack('>L', x))
  84.  
  85.  
  86. def _write_string(f, s):
  87.     if len(s) > 255:
  88.         raise ValueError('string exceeds maximum pstring length')
  89.     
  90.     f.write(chr(len(s)))
  91.     f.write(s)
  92.     if len(s) & 1 == 0:
  93.         f.write(chr(0))
  94.     
  95.  
  96.  
  97. def _write_float(f, x):
  98.     import math as math
  99.     if x < 0:
  100.         sign = 32768
  101.         x = x * -1
  102.     else:
  103.         sign = 0
  104.     if x == 0:
  105.         expon = 0
  106.         himant = 0
  107.         lomant = 0
  108.     else:
  109.         (fmant, expon) = math.frexp(x)
  110.         if expon > 16384 or fmant >= 1:
  111.             expon = sign | 32767
  112.             himant = 0
  113.             lomant = 0
  114.         else:
  115.             expon = expon + 16382
  116.             if expon < 0:
  117.                 fmant = math.ldexp(fmant, expon)
  118.                 expon = 0
  119.             
  120.             expon = expon | sign
  121.             fmant = math.ldexp(fmant, 32)
  122.             fsmant = math.floor(fmant)
  123.             himant = long(fsmant)
  124.             fmant = math.ldexp(fmant - fsmant, 32)
  125.             fsmant = math.floor(fmant)
  126.             lomant = long(fsmant)
  127.     _write_short(f, expon)
  128.     _write_long(f, himant)
  129.     _write_long(f, lomant)
  130.  
  131. from chunk import Chunk
  132.  
  133. class Aifc_read:
  134.     
  135.     def initfp(self, file):
  136.         self._version = 0
  137.         self._decomp = None
  138.         self._convert = None
  139.         self._markers = []
  140.         self._soundpos = 0
  141.         self._file = Chunk(file)
  142.         if self._file.getname() != 'FORM':
  143.             raise Error, 'file does not start with FORM id'
  144.         
  145.         formdata = self._file.read(4)
  146.         if formdata == 'AIFF':
  147.             self._aifc = 0
  148.         elif formdata == 'AIFC':
  149.             self._aifc = 1
  150.         else:
  151.             raise Error, 'not an AIFF or AIFF-C file'
  152.         self._comm_chunk_read = 0
  153.         while None:
  154.             self._ssnd_seek_needed = 1
  155.             
  156.             try:
  157.                 chunk = Chunk(self._file)
  158.             except EOFError:
  159.                 break
  160.  
  161.             chunkname = chunk.getname()
  162.             if chunkname == 'COMM':
  163.                 self._read_comm_chunk(chunk)
  164.                 self._comm_chunk_read = 1
  165.             elif chunkname == 'SSND':
  166.                 self._ssnd_chunk = chunk
  167.                 dummy = chunk.read(8)
  168.                 self._ssnd_seek_needed = 0
  169.             elif chunkname == 'FVER':
  170.                 self._version = _read_ulong(chunk)
  171.             elif chunkname == 'MARK':
  172.                 self._readmark(chunk)
  173.             elif chunkname in _skiplist:
  174.                 pass
  175.             else:
  176.                 raise Error, 'unrecognized chunk type ' + chunk.chunkname
  177.             continue
  178.             if not (self._comm_chunk_read) or not (self._ssnd_chunk):
  179.                 raise Error, 'COMM chunk and/or SSND chunk missing'
  180.             
  181.         if self._aifc and self._decomp:
  182.             import cl as cl
  183.             params = [
  184.                 cl.ORIGINAL_FORMAT,
  185.                 0,
  186.                 cl.BITS_PER_COMPONENT,
  187.                 self._sampwidth * 8,
  188.                 cl.FRAME_RATE,
  189.                 self._framerate]
  190.             if self._nchannels == 1:
  191.                 params[1] = cl.MONO
  192.             elif self._nchannels == 2:
  193.                 params[1] = cl.STEREO_INTERLEAVED
  194.             else:
  195.                 raise Error, 'cannot compress more than 2 channels'
  196.             self._decomp.SetParams(params)
  197.         
  198.  
  199.     
  200.     def __init__(self, f):
  201.         if type(f) == type(''):
  202.             f = __builtin__.open(f, 'rb')
  203.         
  204.         self.initfp(f)
  205.  
  206.     
  207.     def getfp(self):
  208.         return self._file
  209.  
  210.     
  211.     def rewind(self):
  212.         self._ssnd_seek_needed = 1
  213.         self._soundpos = 0
  214.  
  215.     
  216.     def close(self):
  217.         if self._decomp:
  218.             self._decomp.CloseDecompressor()
  219.             self._decomp = None
  220.         
  221.         self._file = None
  222.  
  223.     
  224.     def tell(self):
  225.         return self._soundpos
  226.  
  227.     
  228.     def getnchannels(self):
  229.         return self._nchannels
  230.  
  231.     
  232.     def getnframes(self):
  233.         return self._nframes
  234.  
  235.     
  236.     def getsampwidth(self):
  237.         return self._sampwidth
  238.  
  239.     
  240.     def getframerate(self):
  241.         return self._framerate
  242.  
  243.     
  244.     def getcomptype(self):
  245.         return self._comptype
  246.  
  247.     
  248.     def getcompname(self):
  249.         return self._compname
  250.  
  251.     
  252.     def getparams(self):
  253.         return (self.getnchannels(), self.getsampwidth(), self.getframerate(), self.getnframes(), self.getcomptype(), self.getcompname())
  254.  
  255.     
  256.     def getmarkers(self):
  257.         if len(self._markers) == 0:
  258.             return None
  259.         
  260.         return self._markers
  261.  
  262.     
  263.     def getmark(self, id):
  264.         for marker in self._markers:
  265.             if id == marker[0]:
  266.                 return marker
  267.                 continue
  268.         
  269.         raise Error, 'marker %r does not exist' % (id,)
  270.  
  271.     
  272.     def setpos(self, pos):
  273.         if pos < 0 or pos > self._nframes:
  274.             raise Error, 'position not in range'
  275.         
  276.         self._soundpos = pos
  277.         self._ssnd_seek_needed = 1
  278.  
  279.     
  280.     def readframes(self, nframes):
  281.         if self._ssnd_seek_needed:
  282.             self._ssnd_chunk.seek(0)
  283.             dummy = self._ssnd_chunk.read(8)
  284.             pos = self._soundpos * self._framesize
  285.             if pos:
  286.                 self._ssnd_chunk.seek(pos + 8)
  287.             
  288.             self._ssnd_seek_needed = 0
  289.         
  290.         if nframes == 0:
  291.             return ''
  292.         
  293.         data = self._ssnd_chunk.read(nframes * self._framesize)
  294.         if self._convert and data:
  295.             data = self._convert(data)
  296.         
  297.         self._soundpos = self._soundpos + len(data) / self._nchannels * self._sampwidth
  298.         return data
  299.  
  300.     
  301.     def _decomp_data(self, data):
  302.         import cl
  303.         dummy = self._decomp.SetParam(cl.FRAME_BUFFER_SIZE, len(data) * 2)
  304.         return self._decomp.Decompress(len(data) / self._nchannels, data)
  305.  
  306.     
  307.     def _ulaw2lin(self, data):
  308.         import audioop as audioop
  309.         return audioop.ulaw2lin(data, 2)
  310.  
  311.     
  312.     def _adpcm2lin(self, data):
  313.         import audioop
  314.         if not hasattr(self, '_adpcmstate'):
  315.             self._adpcmstate = None
  316.         
  317.         (data, self._adpcmstate) = audioop.adpcm2lin(data, 2, self._adpcmstate)
  318.         return data
  319.  
  320.     
  321.     def _read_comm_chunk(self, chunk):
  322.         self._nchannels = _read_short(chunk)
  323.         self._nframes = _read_long(chunk)
  324.         self._sampwidth = (_read_short(chunk) + 7) / 8
  325.         self._framerate = int(_read_float(chunk))
  326.         self._framesize = self._nchannels * self._sampwidth
  327.         if self._aifc:
  328.             kludge = 0
  329.             if chunk.chunksize == 18:
  330.                 kludge = 1
  331.                 print 'Warning: bad COMM chunk size'
  332.                 chunk.chunksize = 23
  333.             
  334.             self._comptype = chunk.read(4)
  335.             if kludge:
  336.                 length = ord(chunk.file.read(1))
  337.                 if length & 1 == 0:
  338.                     length = length + 1
  339.                 
  340.                 chunk.chunksize = chunk.chunksize + length
  341.                 chunk.file.seek(-1, 1)
  342.             
  343.             self._compname = _read_string(chunk)
  344.             if self._comptype != 'NONE':
  345.                 if self._comptype == 'G722':
  346.                     
  347.                     try:
  348.                         import audioop
  349.                     except ImportError:
  350.                         pass
  351.  
  352.                     self._convert = self._adpcm2lin
  353.                     self._framesize = self._framesize / 4
  354.                     return None
  355.                 
  356.                 
  357.                 try:
  358.                     import cl
  359.                 except ImportError:
  360.                     if self._comptype == 'ULAW':
  361.                         
  362.                         try:
  363.                             import audioop
  364.                             self._convert = self._ulaw2lin
  365.                             self._framesize = self._framesize / 2
  366.                             return None
  367.                         except ImportError:
  368.                             pass
  369.                         except:
  370.                             None<EXCEPTION MATCH>ImportError
  371.                         
  372.  
  373.                     None<EXCEPTION MATCH>ImportError
  374.                     raise Error, 'cannot read compressed AIFF-C files'
  375.  
  376.                 if self._comptype == 'ULAW':
  377.                     scheme = cl.G711_ULAW
  378.                     self._framesize = self._framesize / 2
  379.                 elif self._comptype == 'ALAW':
  380.                     scheme = cl.G711_ALAW
  381.                     self._framesize = self._framesize / 2
  382.                 else:
  383.                     raise Error, 'unsupported compression type'
  384.                 self._decomp = cl.OpenDecompressor(scheme)
  385.                 self._convert = self._decomp_data
  386.             
  387.         else:
  388.             self._comptype = 'NONE'
  389.             self._compname = 'not compressed'
  390.  
  391.     
  392.     def _readmark(self, chunk):
  393.         nmarkers = _read_short(chunk)
  394.         
  395.         try:
  396.             for i in range(nmarkers):
  397.                 id = _read_short(chunk)
  398.                 pos = _read_long(chunk)
  399.                 name = _read_string(chunk)
  400.                 if pos or name:
  401.                     self._markers.append((id, pos, name))
  402.                     continue
  403.         except EOFError:
  404.             print 'Warning: MARK chunk contains only', len(self._markers),
  405.             if len(self._markers) == 1:
  406.                 print 'marker',
  407.             else:
  408.                 print 'markers',
  409.             print 'instead of', nmarkers
  410.  
  411.  
  412.  
  413.  
  414. class Aifc_write:
  415.     
  416.     def __init__(self, f):
  417.         if type(f) == type(''):
  418.             filename = f
  419.             f = __builtin__.open(f, 'wb')
  420.         else:
  421.             filename = '???'
  422.         self.initfp(f)
  423.         if filename[-5:] == '.aiff':
  424.             self._aifc = 0
  425.         else:
  426.             self._aifc = 1
  427.  
  428.     
  429.     def initfp(self, file):
  430.         self._file = file
  431.         self._version = _AIFC_version
  432.         self._comptype = 'NONE'
  433.         self._compname = 'not compressed'
  434.         self._comp = None
  435.         self._convert = None
  436.         self._nchannels = 0
  437.         self._sampwidth = 0
  438.         self._framerate = 0
  439.         self._nframes = 0
  440.         self._nframeswritten = 0
  441.         self._datawritten = 0
  442.         self._datalength = 0
  443.         self._markers = []
  444.         self._marklength = 0
  445.         self._aifc = 1
  446.  
  447.     
  448.     def __del__(self):
  449.         if self._file:
  450.             self.close()
  451.         
  452.  
  453.     
  454.     def aiff(self):
  455.         if self._nframeswritten:
  456.             raise Error, 'cannot change parameters after starting to write'
  457.         
  458.         self._aifc = 0
  459.  
  460.     
  461.     def aifc(self):
  462.         if self._nframeswritten:
  463.             raise Error, 'cannot change parameters after starting to write'
  464.         
  465.         self._aifc = 1
  466.  
  467.     
  468.     def setnchannels(self, nchannels):
  469.         if self._nframeswritten:
  470.             raise Error, 'cannot change parameters after starting to write'
  471.         
  472.         if nchannels < 1:
  473.             raise Error, 'bad # of channels'
  474.         
  475.         self._nchannels = nchannels
  476.  
  477.     
  478.     def getnchannels(self):
  479.         if not self._nchannels:
  480.             raise Error, 'number of channels not set'
  481.         
  482.         return self._nchannels
  483.  
  484.     
  485.     def setsampwidth(self, sampwidth):
  486.         if self._nframeswritten:
  487.             raise Error, 'cannot change parameters after starting to write'
  488.         
  489.         if sampwidth < 1 or sampwidth > 4:
  490.             raise Error, 'bad sample width'
  491.         
  492.         self._sampwidth = sampwidth
  493.  
  494.     
  495.     def getsampwidth(self):
  496.         if not self._sampwidth:
  497.             raise Error, 'sample width not set'
  498.         
  499.         return self._sampwidth
  500.  
  501.     
  502.     def setframerate(self, framerate):
  503.         if self._nframeswritten:
  504.             raise Error, 'cannot change parameters after starting to write'
  505.         
  506.         if framerate <= 0:
  507.             raise Error, 'bad frame rate'
  508.         
  509.         self._framerate = framerate
  510.  
  511.     
  512.     def getframerate(self):
  513.         if not self._framerate:
  514.             raise Error, 'frame rate not set'
  515.         
  516.         return self._framerate
  517.  
  518.     
  519.     def setnframes(self, nframes):
  520.         if self._nframeswritten:
  521.             raise Error, 'cannot change parameters after starting to write'
  522.         
  523.         self._nframes = nframes
  524.  
  525.     
  526.     def getnframes(self):
  527.         return self._nframeswritten
  528.  
  529.     
  530.     def setcomptype(self, comptype, compname):
  531.         if self._nframeswritten:
  532.             raise Error, 'cannot change parameters after starting to write'
  533.         
  534.         if comptype not in ('NONE', 'ULAW', 'ALAW', 'G722'):
  535.             raise Error, 'unsupported compression type'
  536.         
  537.         self._comptype = comptype
  538.         self._compname = compname
  539.  
  540.     
  541.     def getcomptype(self):
  542.         return self._comptype
  543.  
  544.     
  545.     def getcompname(self):
  546.         return self._compname
  547.  
  548.     
  549.     def setparams(self, .1):
  550.         (nchannels, sampwidth, framerate, nframes, comptype, compname) = .1
  551.         if self._nframeswritten:
  552.             raise Error, 'cannot change parameters after starting to write'
  553.         
  554.         if comptype not in ('NONE', 'ULAW', 'ALAW', 'G722'):
  555.             raise Error, 'unsupported compression type'
  556.         
  557.         self.setnchannels(nchannels)
  558.         self.setsampwidth(sampwidth)
  559.         self.setframerate(framerate)
  560.         self.setnframes(nframes)
  561.         self.setcomptype(comptype, compname)
  562.  
  563.     
  564.     def getparams(self):
  565.         if not (self._nchannels) and not (self._sampwidth) or not (self._framerate):
  566.             raise Error, 'not all parameters set'
  567.         
  568.         return (self._nchannels, self._sampwidth, self._framerate, self._nframes, self._comptype, self._compname)
  569.  
  570.     
  571.     def setmark(self, id, pos, name):
  572.         if id <= 0:
  573.             raise Error, 'marker ID must be > 0'
  574.         
  575.         if pos < 0:
  576.             raise Error, 'marker position must be >= 0'
  577.         
  578.         if type(name) != type(''):
  579.             raise Error, 'marker name must be a string'
  580.         
  581.         for i in range(len(self._markers)):
  582.             if id == self._markers[i][0]:
  583.                 self._markers[i] = (id, pos, name)
  584.                 return None
  585.                 continue
  586.         
  587.         self._markers.append((id, pos, name))
  588.  
  589.     
  590.     def getmark(self, id):
  591.         for marker in self._markers:
  592.             if id == marker[0]:
  593.                 return marker
  594.                 continue
  595.         
  596.         raise Error, 'marker %r does not exist' % (id,)
  597.  
  598.     
  599.     def getmarkers(self):
  600.         if len(self._markers) == 0:
  601.             return None
  602.         
  603.         return self._markers
  604.  
  605.     
  606.     def tell(self):
  607.         return self._nframeswritten
  608.  
  609.     
  610.     def writeframesraw(self, data):
  611.         self._ensure_header_written(len(data))
  612.         nframes = len(data) / self._sampwidth * self._nchannels
  613.         if self._convert:
  614.             data = self._convert(data)
  615.         
  616.         self._file.write(data)
  617.         self._nframeswritten = self._nframeswritten + nframes
  618.         self._datawritten = self._datawritten + len(data)
  619.  
  620.     
  621.     def writeframes(self, data):
  622.         self.writeframesraw(data)
  623.         if self._nframeswritten != self._nframes or self._datalength != self._datawritten:
  624.             self._patchheader()
  625.         
  626.  
  627.     
  628.     def close(self):
  629.         self._ensure_header_written(0)
  630.         if self._datawritten & 1:
  631.             self._file.write(chr(0))
  632.             self._datawritten = self._datawritten + 1
  633.         
  634.         self._writemarkers()
  635.         if self._nframeswritten != self._nframes and self._datalength != self._datawritten or self._marklength:
  636.             self._patchheader()
  637.         
  638.         if self._comp:
  639.             self._comp.CloseCompressor()
  640.             self._comp = None
  641.         
  642.         self._file.flush()
  643.         self._file = None
  644.  
  645.     
  646.     def _comp_data(self, data):
  647.         import cl
  648.         dummy = self._comp.SetParam(cl.FRAME_BUFFER_SIZE, len(data))
  649.         dummy = self._comp.SetParam(cl.COMPRESSED_BUFFER_SIZE, len(data))
  650.         return self._comp.Compress(self._nframes, data)
  651.  
  652.     
  653.     def _lin2ulaw(self, data):
  654.         import audioop
  655.         return audioop.lin2ulaw(data, 2)
  656.  
  657.     
  658.     def _lin2adpcm(self, data):
  659.         import audioop
  660.         if not hasattr(self, '_adpcmstate'):
  661.             self._adpcmstate = None
  662.         
  663.         (data, self._adpcmstate) = audioop.lin2adpcm(data, 2, self._adpcmstate)
  664.         return data
  665.  
  666.     
  667.     def _ensure_header_written(self, datasize):
  668.         if not self._nframeswritten:
  669.             if self._comptype in ('ULAW', 'ALAW'):
  670.                 if not self._sampwidth:
  671.                     self._sampwidth = 2
  672.                 
  673.                 if self._sampwidth != 2:
  674.                     raise Error, 'sample width must be 2 when compressing with ULAW or ALAW'
  675.                 
  676.             
  677.             if self._comptype == 'G722':
  678.                 if not self._sampwidth:
  679.                     self._sampwidth = 2
  680.                 
  681.                 if self._sampwidth != 2:
  682.                     raise Error, 'sample width must be 2 when compressing with G7.22 (ADPCM)'
  683.                 
  684.             
  685.             if not self._nchannels:
  686.                 raise Error, '# channels not specified'
  687.             
  688.             if not self._sampwidth:
  689.                 raise Error, 'sample width not specified'
  690.             
  691.             if not self._framerate:
  692.                 raise Error, 'sampling rate not specified'
  693.             
  694.             self._write_header(datasize)
  695.         
  696.  
  697.     
  698.     def _init_compression(self):
  699.         if self._comptype == 'G722':
  700.             self._convert = self._lin2adpcm
  701.             return None
  702.         
  703.         
  704.         try:
  705.             import cl
  706.         except ImportError:
  707.             if self._comptype == 'ULAW':
  708.                 
  709.                 try:
  710.                     import audioop
  711.                     self._convert = self._lin2ulaw
  712.                     return None
  713.                 except ImportError:
  714.                     pass
  715.                 except:
  716.                     None<EXCEPTION MATCH>ImportError
  717.                 
  718.  
  719.             None<EXCEPTION MATCH>ImportError
  720.             raise Error, 'cannot write compressed AIFF-C files'
  721.  
  722.         if self._comptype == 'ULAW':
  723.             scheme = cl.G711_ULAW
  724.         elif self._comptype == 'ALAW':
  725.             scheme = cl.G711_ALAW
  726.         else:
  727.             raise Error, 'unsupported compression type'
  728.         self._comp = cl.OpenCompressor(scheme)
  729.         params = [
  730.             cl.ORIGINAL_FORMAT,
  731.             0,
  732.             cl.BITS_PER_COMPONENT,
  733.             self._sampwidth * 8,
  734.             cl.FRAME_RATE,
  735.             self._framerate,
  736.             cl.FRAME_BUFFER_SIZE,
  737.             100,
  738.             cl.COMPRESSED_BUFFER_SIZE,
  739.             100]
  740.         if self._nchannels == 1:
  741.             params[1] = cl.MONO
  742.         elif self._nchannels == 2:
  743.             params[1] = cl.STEREO_INTERLEAVED
  744.         else:
  745.             raise Error, 'cannot compress more than 2 channels'
  746.         self._comp.SetParams(params)
  747.         dummy = self._comp.Compress(0, '')
  748.         self._convert = self._comp_data
  749.  
  750.     
  751.     def _write_header(self, initlength):
  752.         if self._aifc and self._comptype != 'NONE':
  753.             self._init_compression()
  754.         
  755.         self._file.write('FORM')
  756.         if not self._nframes:
  757.             self._nframes = initlength / self._nchannels * self._sampwidth
  758.         
  759.         self._datalength = self._nframes * self._nchannels * self._sampwidth
  760.         if self._datalength & 1:
  761.             self._datalength = self._datalength + 1
  762.         
  763.         if self._aifc:
  764.             if self._comptype in ('ULAW', 'ALAW'):
  765.                 self._datalength = self._datalength / 2
  766.                 if self._datalength & 1:
  767.                     self._datalength = self._datalength + 1
  768.                 
  769.             elif self._comptype == 'G722':
  770.                 self._datalength = (self._datalength + 3) / 4
  771.                 if self._datalength & 1:
  772.                     self._datalength = self._datalength + 1
  773.                 
  774.             
  775.         
  776.         self._form_length_pos = self._file.tell()
  777.         commlength = self._write_form_length(self._datalength)
  778.         if self._aifc:
  779.             self._file.write('AIFC')
  780.             self._file.write('FVER')
  781.             _write_long(self._file, 4)
  782.             _write_long(self._file, self._version)
  783.         else:
  784.             self._file.write('AIFF')
  785.         self._file.write('COMM')
  786.         _write_long(self._file, commlength)
  787.         _write_short(self._file, self._nchannels)
  788.         self._nframes_pos = self._file.tell()
  789.         _write_long(self._file, self._nframes)
  790.         _write_short(self._file, self._sampwidth * 8)
  791.         _write_float(self._file, self._framerate)
  792.         if self._aifc:
  793.             self._file.write(self._comptype)
  794.             _write_string(self._file, self._compname)
  795.         
  796.         self._file.write('SSND')
  797.         self._ssnd_length_pos = self._file.tell()
  798.         _write_long(self._file, self._datalength + 8)
  799.         _write_long(self._file, 0)
  800.         _write_long(self._file, 0)
  801.  
  802.     
  803.     def _write_form_length(self, datalength):
  804.         if self._aifc:
  805.             commlength = 23 + len(self._compname)
  806.             if commlength & 1:
  807.                 commlength = commlength + 1
  808.             
  809.             verslength = 12
  810.         else:
  811.             commlength = 18
  812.             verslength = 0
  813.         _write_long(self._file, 4 + verslength + self._marklength + 8 + commlength + 16 + datalength)
  814.         return commlength
  815.  
  816.     
  817.     def _patchheader(self):
  818.         curpos = self._file.tell()
  819.         if self._datawritten & 1:
  820.             datalength = self._datawritten + 1
  821.             self._file.write(chr(0))
  822.         else:
  823.             datalength = self._datawritten
  824.         if datalength == self._datalength and self._nframes == self._nframeswritten and self._marklength == 0:
  825.             self._file.seek(curpos, 0)
  826.             return None
  827.         
  828.         self._file.seek(self._form_length_pos, 0)
  829.         dummy = self._write_form_length(datalength)
  830.         self._file.seek(self._nframes_pos, 0)
  831.         _write_long(self._file, self._nframeswritten)
  832.         self._file.seek(self._ssnd_length_pos, 0)
  833.         _write_long(self._file, datalength + 8)
  834.         self._file.seek(curpos, 0)
  835.         self._nframes = self._nframeswritten
  836.         self._datalength = datalength
  837.  
  838.     
  839.     def _writemarkers(self):
  840.         if len(self._markers) == 0:
  841.             return None
  842.         
  843.         self._file.write('MARK')
  844.         length = 2
  845.         for marker in self._markers:
  846.             (id, pos, name) = marker
  847.             length = length + len(name) + 1 + 6
  848.             if len(name) & 1 == 0:
  849.                 length = length + 1
  850.                 continue
  851.         
  852.         _write_long(self._file, length)
  853.         self._marklength = length + 8
  854.         _write_short(self._file, len(self._markers))
  855.         for marker in self._markers:
  856.             (id, pos, name) = marker
  857.             _write_short(self._file, id)
  858.             _write_long(self._file, pos)
  859.             _write_string(self._file, name)
  860.         
  861.  
  862.  
  863.  
  864. def open(f, mode = None):
  865.     if mode is None:
  866.         if hasattr(f, 'mode'):
  867.             mode = f.mode
  868.         else:
  869.             mode = 'rb'
  870.     
  871.     if mode in ('r', 'rb'):
  872.         return Aifc_read(f)
  873.     elif mode in ('w', 'wb'):
  874.         return Aifc_write(f)
  875.     else:
  876.         raise Error, "mode must be 'r', 'rb', 'w', or 'wb'"
  877.  
  878. openfp = open
  879. if __name__ == '__main__':
  880.     import sys
  881.     if not sys.argv[1:]:
  882.         sys.argv.append('/usr/demos/data/audio/bach.aiff')
  883.     
  884.     fn = sys.argv[1]
  885.     f = open(fn, 'r')
  886.     print 'Reading', fn
  887.     print 'nchannels =', f.getnchannels()
  888.     print 'nframes   =', f.getnframes()
  889.     print 'sampwidth =', f.getsampwidth()
  890.     print 'framerate =', f.getframerate()
  891.     print 'comptype  =', f.getcomptype()
  892.     print 'compname  =', f.getcompname()
  893.     if sys.argv[2:]:
  894.         gn = sys.argv[2]
  895.         print 'Writing', gn
  896.         g = open(gn, 'w')
  897.         g.setparams(f.getparams())
  898.         while None:
  899.             data = f.readframes(1024)
  900.             if not data:
  901.                 break
  902.             
  903.             continue
  904.             g.close()
  905.             f.close()
  906.             print 'Done.'
  907.     sys.argv[2:]
  908.  
  909.